
import apkparser
def get_apk_signature_with_apkparser(apk_path):
    """使用 apkparser 库获取 APK 签名信息 Args: apk_path: APK 文件路径 Returns: 一个包含签名信息的列表，或者 None 如果没有找到签名信息 """
    try:
        apk = apkparser.APK(apk_path)
        signatures = apk.get_signatures()
        # 使用 get_signatures() 获取签名信息
        return signatures
    except Exception as e:
        print(f"获取签名信息失败：{e}")
        return None
    # 示例：获取 APK 签名信息
apk_path = "C:\file_data\pycharm_project\django\apk_parse_model\测试apk.apk"

from androguard.core.apk import APK
from androguard.core.apk import show_Certificate
import hashlib


# 写一个函数计算md5值


def get_md5_hash(file_path):
    """
    计算并返回给定文件的 MD5 哈希值。
    :param file_path: 要计算 MD5 哈希值的文件路径
    :return: 文件的 MD5 哈希值（十六进制字符串）
    """
    hash_md5 = hashlib.md5()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()


apk_path = "C:\\file_data\\pycharm_project\\django\\apk_parse_model\\测试apk.apk"

def get_signature(apk_path):
    a = APK(apk_path)
    # 是否签名以及v1\v2\v3是否签名
    is_signed = a.is_signed()
    is_signed_v1 = a.is_signed_v1()
    is_signed_v2 = a.is_signed_v2()
    is_signed_v3 = a.is_signed_v3()
    # 是否有效
    is_valid = a.is_valid_APK()
    # 签名名称
    cert = a.get_certificates()[0]
    # sha1和sha256指纹信息
    print(cert.subject.native)
    print(cert.issuer.native)
    sha1 = cert.sha1_fingerprint
    sha256 = cert.sha256_fingerprint
    # 获取签名证书发布信息
    # md5
    # md5 = get_md5_hash(apk_path)
    # 国家
    signature_name = a.get_signature_name()

    country = cert.issuer.native['country_name']
    # 省市
    province = cert.issuer.native['state_or_province_name']
    # 城市
    city = cert.issuer.native['locality_name']
    # 组织
    organization = cert.issuer.native['organization_name']
    # 服务器或服务名称
    serviceName = cert.issuer.native['common_name']
    show_Certificate(cert)
    print("解析完成")



import tempfile
import io
from django.core.files.base import ContentFile

# --------------------------获取图片图标
from androguard.core.apk import APK
apk_path = "C:\\file_data\\pycharm_project\\django\\apk_parse_model\\测试apk.apk"
import os
import tempfile
from androguard.misc import AnalyzeAPK


def get_icon_file(apk_path):
    a = APK(apk_path)
    icon_path = a.get_app_icon()
    print(icon_path)
    icon_path = "res/drawable-xxhdpi-v4/icon.png"
    icon_path = "D:\\file_data\涉诈APP\\apktools\\" + str(icon_path)
    if os.path.exists(icon_path):
        with open(icon_path, "rb") as f:
            icon_data = f.read()
        print(type(icon_data))
        return icon_data
    else:
        print("包催哦了")


def get_permission(apk_path):
    a = APK(apk_path)
    detail_permission = a.get_details_permissions()
    print(detail_permission)
    temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
    temp_file.write(str(detail_permission))
    temp_file.flush()
    temp_file.close()



    print(type(detail_permission))
    for k in detail_permission:
        print(k)
        print(detail_permission[k])
        print(detail_permission[k][0])
        print(detail_permission[k][1])
        print(detail_permission[k][2])

    print("--------------------------------活动-----------------------------------------------")
    main_activities = a.get_main_activities()
    detail_activities = a.get_activities()
    print(main_activities)
    print(detail_activities)


# ---------------------获取Java源码-----------------------------
def get_java_code(apk_path):
    a, d, dx = AnalyzeAPK(apk_path)
    java_code = ""
    for dex in d:
        for class_def in dex.get_classes():
            smali_class = class_def.get_source()
            class_name = class_def.get_name()
            java_code += class_name + "\n" + smali_class + "\n\n"
    text_io_wrapper = io.StringIO(java_code)
    # 读取_io.TextIOWrapper对象的内容
    file_content = text_io_wrapper.getvalue().encode('utf-8')  # 转换为字节串，因为FileField期望的是字节类型的数据
    # 创建一个ContentFile对象
    content_file = ContentFile(file_content, name="app_name" + '.txt')  # 作为文件的名称被保存
    print(content_file)

# -------------------------处理related_site信息-----------------------------------------

import paramiko
import time
# 通过kali虚拟机使用apk2url技术解析apk内的url（以列表的形式返回）
def parse_urls(apk_name):
    # 将pycharm与kali虚拟机连接
    # 连接设置
    # 使用root用户登录kali虚拟机
    ssh_host = '192.168.204.128'  # 替Kali 虚拟机 IP 地址
    ssh_user = 'root'  # Kali 用户名
    ssh_password = '20050213w'  # Kali 密码

    # 创建 SSH 连接对象
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    # 连接到 Kali 虚拟机
    try:
        ssh.connect(hostname=ssh_host, username=ssh_user, password=ssh_password)
        print('SSH connection established')
    except Exception as e:
        print(f"连接失败：{e}")
        exit(1)
    # apk2url通过使用apktool和aapt两个工具对apk文件进行综合解析
    # 解析之后的url
    # _endpoints.txt //包含具有完整 URL 路径的终结点,更加的详细（选择这个）-写入文件，以文件的形式存储
    # 动态解析通联地址主要是域名
    # 文件在kali虚拟机中的路径

    # 执行解析命令和读取解析后结果的命令
    # 执行解析的命令
    command1 = "apk2url /mnt/hgfs/apk_file/" + apk_name +".apk"
    # exec_conmand每次开启的是一个新的shell，无法实现实时交互
    # invoke_shell执行多条连续的指令（同一个shell）
    # 创建一个shell会话
    shell = ssh.invoke_shell()

    # 执行多条命令
    # cd到特定的文件夹中，使用root解析会将解析内容解析在相应的子文件夹中
    parse_urls_path = "/home/wzd/parse_apk_url/"
    shell.send(parse_urls_path + "\n")
    time.sleep(1)
    shell.send(command1 + "\n")
    time.sleep(1)
    shell.send('y\n')
    time.sleep(200)
    # 尝试接收最多65535字节的数据输出
    recv_data = shell.recv(65535)
    # 将接收到的字节数据解码为字符串，并添加到输出字符串中
    output = recv_data.decode('utf-8')

    print(output)
    # 关闭连接
    shell.close()

    # 执行读取的命令
    _endpoints_path = parse_urls_path + 'endpoints//' + apk_name + '_endpoints.txt'
    command2 = "cat " + _endpoints_path
    stdin, stdout, stderr = ssh.exec_command(command2)
    res_url = []
    for line in stdout.readlines():
        if not line.strip():
            continue
        res_url.append(line.strip())
    print(res_url)

    # 返回url内容-列表
    # 关闭ssh连接
    ssh.close()

    return res_url


import pandas as pd
import pymysql
from sqlalchemy import create_engine
black_excel = ['gamble.xlsx', 'sex.xlsx', 'black.xlsx', 'scam.xlsx']
white_excel = ['white.xlsx']
init_path = "C:\\file_data\涉诈APP\最新数据集\\batch1-4_labels_guide_update\\"

def writeDatabase(excel_file, table_name):
    # MySQL连接信息
    host = 'localhost'
    user = 'root'
    password = '20050213w'
    database = 'appdescams'

    # 使用pandas读取Excel文件
    df = pd.read_excel(excel_file)

    # MySQL连接字符串（使用pymysql）
    connection_string = f'mysql+pymysql://{user}:{password}@{host}/{database}'

    # 创建SQLAlchemy引擎
    engine = create_engine(connection_string)

    # 将DataFrame写入MySQL表
    # 注意：如果表不存在，你需要先创建它，或者设置if_exists参数为'replace'（这将删除旧表并创建新表，慎用）
    # 这里我们假设表已经存在，并且列与DataFrame的列匹配
    # 使用Engine获取一个Connection对象
    with engine.connect() as connection:
        df.to_sql(table_name, con=connection, if_exists='append', index=False)

    print(f"数据已成功写入到MySQL的{table_name}表中。")
import mysql.connector
def excle2mysql(excel_file,my_table):

    # 连接 MySQL 数据库
    mydb = mysql.connector.connect(
        host="localhost",
        user="root",
        password="20050213w",
        database="appdescams"
    )

    # 创建一个游标对象
    mycursor = mydb.cursor()

    # 读取 Excel 文件
    df = pd.read_excel(excel_file)
    df.fillna(method="ffill", inplace=True)

    # 将数据插入 MySQL 数据库
    for index, row in df.iterrows():
        sql = "INSERT INTO " + my_table + " (packageName, apkName, md5, result) VALUES (%s, %s, %s, %s)"
        val = (row['packageName'], row['apkName'], row['md5'], row['result'])
        mycursor.execute(sql, val)

    # 提交更改
    mydb.commit()

    # 关闭连接
    mycursor.close()
    mydb.close()

    print("数据已成功写入 MySQL 数据库！")
if __name__ == '__main__':
    for i in black_excel:
        # writeDatabase(init_path + i, 'black_apk')
        excle2mysql(init_path+i,"black_apk")
        print(i+"写入成功")
    # writeDatabase(init_path + white_excel[0], 'white_apk')
    excle2mysql(init_path+white_excel[0],"white_apk")
    print(white_excel[0]+"写入成功")
    # get_permission(apk_path)
    # get_java_code(apk_path)
    # get_signature(apk_path)
    # parse_urls("00a918d86701af1b1acf12cfce132c01")



